home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 037a / mou_rout.zip / PAGEFLIP.PAS < prev    next >
Pascal/Delphi Source File  |  1990-05-08  |  5KB  |  113 lines

  1. From usc!snorkelwacker!ira.uka.de!news Tue May  8 12:02:49 PDT 1990
  2. Article 2637 of comp.lang.pascal:
  3. Path: jarthur!usc!snorkelwacker!ira.uka.de!news
  4. >From: s_rohrbacher
  5. Newsgroups: comp.lang.pascal
  6. Subject: Re: flicker-free animation with TP
  7. Message-ID: <90.127.13:27:55@ira.uka.de>
  8. Date: 7 May 90 20:24:27 GMT
  9. Sender: news@ira.uka.de (USENET News System)
  10. Reply-To: s_rohrbacher
  11. Organization: University of Karlsruhe, FRG
  12. Lines: 96
  13.  
  14. Some days ago, one of you asked for a solution to do fast flicker-free
  15. animation in TurboPascal. I myself had the same problem and circumvented it by
  16. a simple technique called "page-flipping": nearly every graphic card has 2
  17. independent graphic pages, so it is possible to draw at one page while showing
  18. the other. If the "background" page is finished, you just "flip" the pages:
  19. thus, at any time all actions take place in the background and you get a smooth
  20. animation!
  21. In TP, you choose the visible page with "SetVisualPage" and the working page
  22. with "SetActivePage". - Take the following program as an example: it animates a
  23. hatched square, either with or without page-flipping (adapt proc. "Initialize"
  24. if you have a Hercules instead of an EGA/VGA):
  25.  
  26. PROGRAM page_flipping_demo; {by Kai Rohrbacher, TP 5.0, 4/25/90}
  27. USES Crt,Graph;
  28. CONST seeing_page:Word=0; {number of actual seen page}
  29. VAR GraphDriver,GraphMode,x,y,xold,yold,xtemp,ytemp:Integer;
  30.     Sprite:Pointer; {pointer to sprite-data}
  31.     ch:char;
  32.     WITH_PAGE_FLIPPING:Boolean; {demonstration mode}
  33.  
  34. PROCEDURE Initialize; {set any graphic-mode with 2 pages; here EGA}
  35. BEGIN
  36.  GraphDriver:=EGA; GraphMode:=EGAHi;
  37.  InitGraph(GraphDriver,GraphMode,'');
  38.  IF GraphResult<>grOK THEN BEGIN Writeln('No EGA!'); Halt(1) END;
  39. END;
  40.  
  41. PROCEDURE initialize_flip; {clear pages; show one, work on the other}
  42. BEGIN
  43.  setactivepage(0); cleardevice;
  44.  outtextxy(100,0,'Page 0 - Use I,J,K,M, Q=Quit');
  45.  setactivepage(1); cleardevice;
  46.  outtextxy(100,0,'Page 1 - Use I,J,K,M, Q=Quit');
  47.  setactivepage(1-seeing_page); setvisualpage(seeing_page)
  48. END;
  49.  
  50. PROCEDURE flip; {exchange active & visible page}
  51. BEGIN
  52.  setactivepage(seeing_page); seeing_page:=1-seeing_page;
  53.  setvisualpage(seeing_page);
  54. END;
  55.  
  56. PROCEDURE update_sprite; {works totally on background page!}
  57. BEGIN
  58.  IF (xold<>-1) AND (yold<>-1) THEN PutImage(xold,yold,sprite^,XORput);
  59.  PutImage(x,y,sprite^,XORput)
  60. END;
  61.  
  62. BEGIN {main}
  63.  Write('With (1) or without (2) pageflipping? ');
  64.  REPEAT ch:=UpCase(readkey) UNTIL ch in ['1','2'];
  65.  WITH_PAGE_FLIPPING:=ch='1'; {set mode}
  66.  Initialize;
  67.  {generate sprite and save it on TP's stack:}
  68.  rectangle(0,0,50,50); setFillStyle(Hatchfill,white);
  69.  FloodFill(1,1,white); GetMem(sprite,ImageSize(0,0,50,50));
  70.  GetImage(0,0,50,50,sprite^); cleardevice;
  71.  outtextxy(0,0,'Use I,J,K,M, Q=Quit');
  72.  IF WITH_PAGE_FLIPPING THEN initialize_flip;
  73.  xold:=-1; yold:=-1; xtemp:=-1; ytemp:=-1; {-1=flag: 'currently not used'}
  74.  x:=100; y:=100; {starting point of animation}
  75.  REPEAT
  76.   ch:=UpCase(readkey);
  77.   CASE ch OF {what action?}
  78.    'J':dec(x); 'K':inc(x); 'I':dec(y); 'M':inc(y); 'Q':;
  79.    ELSE BEGIN sound(1200); delay(100); nosound END
  80.   END;
  81.  update_sprite; {remove old, draw new}
  82.  IF WITH_PAGE_FLIPPING
  83.   THEN BEGIN {shift through: x->xtemp->xold, y->ytemp->yoldf}
  84.         xold:=xtemp; yold:=ytemp; xtemp:=x; ytemp:=y; flip
  85.        END   {so after 2 cycles the sprite is cleared from correct page}
  86.   ELSE BEGIN xold:=x; yold:=y END; {no flipping=no such mechanism needed}
  87.  UNTIL ch='Q';
  88.  FreeMem(sprite,ImageSize(0,0,50,50)); closegraph; {end correctly}
  89. END.
  90.  
  91. The only thing to notice is that you have to store coordinates for 2 
  92. cycles to be able to erase a sprite on the correct page.
  93. There remains one last possibility of (minor) flicker: depending on your
  94. PC's BIOS, it may happen that programs flip pages while the cathode ray
  95. is in the midst of displaying data: in that case you have to bypass BIOS
  96. and synchronize switching directly with the "vertical retrace" (the 
  97. moment while the cathode ray moves back from the bottom-right to the
  98. upper-left corner). As a time-critical task (the corresponding bit at 
  99. port $3DA, Bitmask 8 (or $3BA, Bitmask 128 for HGC) toggles with 50Hz),
  100. you should do that in assembler.
  101. To all of you who hope to program an arcade game completely in TP, be 
  102. warned: TP is just to slow to do the job (try to animate -say- 30 
  103. sprites at once)! Me too, I had to discover this (3 years ago) -and came
  104. out with a self-written TP-unit, spritedesigner and a lot of integrated
  105. assembler stuff (for the animation itself, background-saving, collision
  106. detection, scrolling and that things).
  107. I am planning to release this package (as shareware) here in FRG very
  108. soon, so if you are interested, watch out!
  109. S_ROHRBACHER@IRAV1.IRA.UKA.DE    (Kai Rohrbacher)        
  110.  
  111.  
  112. 
  113.